#include "Module/SqlSvrConnConfigWidget.qth"
#include "Module/SqlSvrConnConfigWidget.moh"
#include "Storage/SqlSvrConnectionConfig.hpp"
#include "CaseDB/SqlSvrConnection.hpp"
#include "CaseDB/DatabaseError.hpp"
#include "utils/auto_cleanup.hpp"
#include <QtGui/QGridLayout>
#include <QtGui/QLineEdit>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QMessageBox>
#include <QtGui/QProgressDialog>
#include <QtGui/QApplication>
#include <boost/bind.hpp>
#include <sstream>

namespace Module
{


// ---------------------------------------------------------------------------------------------------------------------

SqlSvrConnConfigWidget::SqlSvrConnConfigWidget( QWidget* pParent /*= NULL*/ )
	: ConnectionConfigWidget( pParent)
{
	QGridLayout* pLayout = qobject_cast<QGridLayout*>( this->layout());

	pServerNameEditor_ = new QLineEdit();
	QLabel* pSvrNameLbl = new QLabel( pServerNameEditor_);
	pSvrNameLbl->setText( tr( "Server name:"));
	pLayout->addWidget( pSvrNameLbl, 1, 0);
	pLayout->addWidget( pServerNameEditor_, 1, 1);

	pDBNameEditor_ = new QLineEdit();
	QLabel* pDbNameLbl = new QLabel( pDBNameEditor_);
	pDbNameLbl->setText( tr( "Database: "));
	pLayout->addWidget( pDbNameLbl, 2, 0);
	pLayout->addWidget( pDBNameEditor_, 2, 1);

	pUserNameEditor_ = new QLineEdit();
	QLabel* pUserNameLbl = new QLabel( pUserNameEditor_);
	pUserNameLbl->setText( tr( "User name"));
	pLayout->addWidget( pUserNameLbl, 3, 0);
	pLayout->addWidget( pUserNameEditor_, 3, 1);

	pPasswordEditor_ = new QLineEdit();
	pPasswordEditor_->setEchoMode( QLineEdit::Password);
	QLabel* pPwdLbl = new QLabel( pPasswordEditor_);
	pPwdLbl->setText( "Password: ");
	pLayout->addWidget( pPwdLbl, 4, 0);
	pLayout->addWidget( pPasswordEditor_, 4, 1);

	QPushButton* pTestConnectionButton = new QPushButton( tr( "Test connection..."));
	connect( pTestConnectionButton, SIGNAL( clicked( bool)), this, SLOT( testConnection()));
	pLayout->addWidget( pTestConnectionButton, 5, 1);

	// HACK: The initialization should eventually be removed
	pDBNameEditor_->setText( "case");
	pUserNameEditor_->setText( "case");
	pPasswordEditor_->setText( "esac");
	pServerNameEditor_->setText( "CATALIN\\SQLEXPRESS");

	connect( pNameEditor_, SIGNAL( textChanged( const QString&)), this, SLOT( markDirty( const QString& )));
	connect( pUserNameEditor_, SIGNAL( textChanged( const QString&)), this, SLOT( markDirty( const QString& )));
	connect( pServerNameEditor_, SIGNAL( textChanged( const QString&)), this, SLOT( markDirty( const QString& )));
	connect( pDBNameEditor_, SIGNAL( textChanged( const QString&)), this, SLOT( markDirty( const QString& )));
	connect( pPasswordEditor_, SIGNAL( textChanged( const QString&)), this, SLOT( markDirty( const QString& )));
}

// ---------------------------------------------------------------------------------------------------------------------
void SqlSvrConnConfigWidget::testConnection()
{
	std::auto_ptr< QProgressDialog> pProgressDlg( new QProgressDialog( tr("Testing SQL Server Connection. Please wait..."), tr("Cancel"), 0,1, this));
	pProgressDlg->setWindowModality( Qt::WindowModal);
	pProgressDlg->show();
	try
	{
		utils::auto_cleanup cursorOverride( 
			boost::bind( &QApplication::setOverrideCursor, QCursor( Qt::WaitCursor)),
			&QApplication::restoreOverrideCursor);

		CaseDB::SqlSvrConnection conn( "!!SqlSvrConnectionTest", this->connectionString());
		conn.open();
		pProgressDlg->setValue( 1);
		pProgressDlg = std::auto_ptr< QProgressDialog>();
		conn.close();
	}
	catch( CaseDB::DatabaseError& e)
	{
		QString message = tr("Connection failed.\n\tReason:\n");
		message+=e.what();
		QMessageBox::critical( this, tr( "Testing SQL Server Connection"), message);
		return;
	}
	QMessageBox::information( this, tr( "Testing SQL Server Connection"), tr( "Connection successful"));
}

// ---------------------------------------------------------------------------------------------------------------------

std::string SqlSvrConnConfigWidget::connectionString() const
{
	std::ostringstream os;
	os	<< "DRIVER=SQL Server;" 
		<< "UID=" << this->userName().toUtf8().data() << ";"
		<< "DATABASE=" << this->databaseName().toUtf8().data() << ";"
		<< "SERVER=" << this->serverName().toUtf8().data() << ";"
		<< "PWD=" << this->password().toUtf8().data();
	return os.str();
}

// ---------------------------------------------------------------------------------------------------------------------

void SqlSvrConnConfigWidget::updateEditedConfig()
{
	if( NULL == pEditedConnConfig_)
	{
		pEditedConnConfig_ = new Storage::SqlSvrConnectionConfig( "dummy");
	}
	Storage::SqlSvrConnectionConfig* pSqlSvrConnCfg = dynamic_cast< Storage::SqlSvrConnectionConfig*>( pEditedConnConfig_);
	pSqlSvrConnCfg->setName( this->connectionName().toStdString());
	pSqlSvrConnCfg->setServerName( this->serverName().toStdString());
	pSqlSvrConnCfg->setUserName( this->userName().toStdString());
	pSqlSvrConnCfg->setPassword( this->password().toStdString());
	pSqlSvrConnCfg->setDatabaseName( this->databaseName().toStdString());
	this->setDirty( false);
}

// ---------------------------------------------------------------------------------------------------------------------

QString SqlSvrConnConfigWidget::serverName() const
{
	return pServerNameEditor_->text().trimmed();
}

// ---------------------------------------------------------------------------------------------------------------------

QString SqlSvrConnConfigWidget::databaseName() const
{
	return pDBNameEditor_->text().trimmed();
}

// ---------------------------------------------------------------------------------------------------------------------

QString SqlSvrConnConfigWidget::userName() const
{
	return pUserNameEditor_->text().trimmed();
}

// ---------------------------------------------------------------------------------------------------------------------

QString SqlSvrConnConfigWidget::password() const
{
	return pPasswordEditor_->text().trimmed();
}

// ---------------------------------------------------------------------------------------------------------------------

void SqlSvrConnConfigWidget::markDirty( const QString& )
{
	this->setDirty( true);
}

// ---------------------------------------------------------------------------------------------------------------------

void SqlSvrConnConfigWidget::setEditedConfig( Storage::ConnectionConfig* pEditedConfig )
{
	ConnectionConfigWidget::setEditedConfig( pEditedConfig);
	Storage::SqlSvrConnectionConfig* pCfg = dynamic_cast< Storage::SqlSvrConnectionConfig*>( pEditedConfig);
	this->setDirty( false);
	pNameEditor_->setText( QString::fromStdString( pCfg->name()));
	pServerNameEditor_->setText( QString::fromStdString( pCfg->serverName()));
	pDBNameEditor_->setText( QString::fromStdString( pCfg->databaseName()));
	pUserNameEditor_->setText( QString::fromStdString( pCfg->userName()));
	pPasswordEditor_->setText( QString::fromStdString( pCfg->password()));
	this->setDirty( false);
}

} // namespace Module
